from rest_framework import serializers
from datetime import datetime, timedelta
from django.contrib.auth import get_user_model
from rest_framework.validators import UniqueValidator
import re

from .models import VerifyCode, UserProfile
from shopping.settings import REGEX_MOBILE

# 获取User模型
User = get_user_model()

class SmsSerializesr(serializers.Serializer):
    """
    注册表单验证
    """
    # 自定义验证字段
    mobile = serializers.CharField(max_length=11, )

    # 验证手机号码(函数名称必须为validate_ + 字段名)
    def validate_mobile(self, mobile):
        # 查询用户是否已注册
        if UserProfile.objects.filter(mobile=mobile, ):
            # 已注册
            raise serializers.ValidationError("用户已存在")

        # 检查手机号合法性
        if not re.match(REGEX_MOBILE, mobile):  # 正则校验
            raise serializers.ValidationError("手机号输入有误请重写输入")

        # 验证码发送频率获取一分钟前的时间
        one_mintes_ago = datetime.now() - timedelta(hours=0, minutes=1, seconds=0)
        # 获取验证时间
        verifycode = VerifyCode.objects.filter(mobile__gte=one_mintes_ago, mobile=mobile).count()
        if verifycode:
            raise serializers.ValidationError("距离上次发送不足60秒")

        return mobile


class UserRegSerializesr(serializers.ModelSerializer):
    """
    用户注册表单验证
    """
    # required=True必填，write_only=True不序列化,因为验证结束这个验证码字段就被删除所以不再需要序列化
    code = serializers.CharField(max_length=4, min_length=4, write_only=True, required=True, label='验证码',
                                 # 字段错误提示
                                 error_messages={
                                     "blank": "请输入验证码",  # 无该字段错误提示，
                                     "required": "请输入验证码",  # 字段为空错误
                                     "max_length": "请输入4位验证码",  # 超过最大值错误
                                     "min_length": "请输入4位验证码",  # 少于最小值错误
                                 })
    # 验证唯一性,账号是否一存在User.objects.all()查询这个表message提示
    username = serializers.CharField(label="用户名", help_text="用户名", required=True, allow_blank=False,
                                     validators=[UniqueValidator(queryset=User.objects.all(), message="用户已经存在")])
    password = serializers.CharField(style={"input_type": "password"}, label="密码", write_only=True)

    def validate_code(self, code):
        # 获取最新的验证码信息
        user = VerifyCode.objects.filter(mobile=self.initial_data["username"]).order_by("-add_time")
        if user:
            user_code = user[0]
            # 获取十分钟前的时间
            time = datetime.now() - timedelta(hours=0, minutes=10, seconds=0)
            if user_code.add_time > time:
                raise serializers.ValidationError("验证码已过期")
            if code != user_code.code:
                raise serializers.ValidationError("验证码错误")
        else:
            raise serializers.ValidationError("验证码错误")

    # 创建新条目时此函数被调用
    def create(self, validated_data):
        user = super(UserRegSerializesr, self).create(validated_data=validated_data)
        # 加密密码
        user.set_password(validated_data["password"])
        # 保存
        user.save()
        return user

    # 全局处理，validate_code只能处理code字段
    def validate(self, attrs):
        # 将用户名赋值给手机号，前端偷懒没传手机号过来
        attrs["mobile"] = attrs["username"]
        # 验证码验证完毕直接删除
        del attrs["code"]
        # 返回数据
        return attrs

    class Meta:
        # 验证模型
        model = UserProfile
        # 验证字段
        fields = ('username', 'code', "mobile", "password")

class UserDetailsSerializesr(serializers.ModelSerializer):

    class Meta:
        model = UserProfile
        fields =  ('name','birthday','gender','mobile','email')